package main

import (
	"io"
	"log"
	"net"
	"strings"
)

type client struct {
	addr string
	conn net.Conn
}
type message struct {
	From string
	To   string
	Msg  string
}

var connMap = make(map[string]*client, 1024)

func init() {
	log.SetFlags(log.Lshortfile | log.Lmicroseconds)
}

func send(msg *message) {
	log.Println(msg)
	_, err := connMap[msg.To].conn.Write([]byte(msg.From + "===>" + msg.Msg + "\n"))
	if err != nil {
		log.Println(err)
		return
	}

}
func handleMsg(b []byte, addr string) {
	str := string(b)
	sp := strings.Split(str, "#")
	//发消息给某人
	m := &message{}

	if len(sp) > 1 {
		m.From = addr
		m.To = sp[0]
		m.Msg = sp[1]
		send(m)
		return
	} else { //发命令
		if str == "LIST" {
			m.From = addr
			m.To = addr
			tmp := []string{}
			for k, _ := range connMap {
				tmp = append(tmp, k)
			}
			l := len(tmp)
			m.Msg = "[列表]" + strings.Join(tmp[:l], ",")
			send(m)
			return
		} else if str == "EXIT" {
			m.From = addr
			m.To = addr
			m.Msg = addr + "[退出]"
			send(m)

			connMap[addr].conn.Close()
		} else {

			for k, _ := range connMap {
				m := &message{}
				m.From = addr
				m.To = k
				m.Msg = "[广播]" + str
				send(m)
			}
			return
		}

	}
}

func process(client *client) {
	conn := client.conn
	defer conn.Close()
	conn.Write([]byte("[系统] 你好! 你的地址是:" + client.addr + "\n LIST-列出当前在线用户\n xxxx:xx#消息内容-发给指定用户,不指定则发给所有人\n EXIT-退出\n"))
	buf := make([]byte, 1024)
	for {
		n, err := conn.Read(buf)
		if err == io.EOF || err != nil {
			log.Println("[断开]", client.addr, err)
			break
		}
		handleMsg(buf[:n], client.addr)

	}

}

func main() {
	listener, err := net.Listen("tcp", ":8989")
	if err != nil {
		log.Panicln(err)
	}
	defer listener.Close()
	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Println(err)
			continue
		}
		addr := conn.RemoteAddr().String()
		log.Println("[新连接]", addr)

		connMap[addr] = &client{addr, conn}
		go process(connMap[addr])
	}
}
